
//
//  CPStringUtil.swift
//  ComponentUtils
//
//  Created by wrs on 2018/7/25.
//  Copyright © 2018年 wrs. All rights reserved.
//

import Foundation

// MARK: - String
public func stringIsNil(_ str: String?) -> Bool {
    if let _ = str {
        return false
    } else {
        return true
    }
}

public func stringIsNotBlank(_ str: String?) -> Bool {
    if stringIsNil(str) {
        return false
    } else {
        if str!.count > 0 {
            return true
        } else {
            return false
        }
    }
}

// MARK: - 中文
public func isIncludeChinese(_ str: String) -> Bool {
    for ch in str.unicodeScalars {
        // 中文字符范围：0x4e00 ~ 0x9fff
        if (0x4e00 < ch.value && ch.value < 0x9fff) {
            return true
        }
    }
    return false
}

// MARK: - 拼音 
public class PinYinSortModel {
 @objc  public  var firstLetter: String?
   public var modelArray: [Any]?
}

fileprivate class PinYinModel {
   @objc var firstLetters: String?
    var model: Any?
}

public protocol SortProtocol {
    var sortValue: String? {get}
}

// sortProperty属性需要加上@objc
public func sortModel(modelArray: [SortProtocol]) -> [PinYinSortModel] {
    var tempModelArray:[PinYinModel] = [PinYinModel]()
    // 封装成模型
    for tempModel in modelArray {
        let pinYinModel: PinYinModel = PinYinModel()
        pinYinModel.model = tempModel

        let sortStr: String? = tempModel.sortValue
        if stringIsNotBlank(sortStr) {
            let firstLetters = getFirstLetters(sortStr!)
            pinYinModel.firstLetters = firstLetters
        } else {
            pinYinModel.firstLetters = ""
        }
       
        tempModelArray.append(pinYinModel)
    }
    
    // 对模型数组排序
    tempModelArray.sort { (model1, model2) -> Bool in
        let result: ComparisonResult = model1.firstLetters!.compare(model2.firstLetters!)
        switch result {
        case .orderedAscending:
            return true
        case .orderedDescending:
            return false
        case .orderedSame:
            return true
        }
    }
    
    // 按字母分组 组装
    var sortArray = [PinYinSortModel]()
    var curSortModel: PinYinSortModel?
    for model in tempModelArray {
        let pinYinModel: PinYinModel = model
        let firstLetter = getFirstLetter(pinYinModel.firstLetters)
        if curSortModel != nil && firstLetter == curSortModel?.firstLetter {
            curSortModel?.modelArray?.append(pinYinModel.model!)
        } else {
            let sortModel: PinYinSortModel = PinYinSortModel()
            sortModel.modelArray = [pinYinModel.model!]
            sortModel.firstLetter = firstLetter
            sortArray.append(sortModel)
            curSortModel = sortModel
        }
    }
    
    // 特殊字符放到最后
    if sortArray.count > 0 {
        let specialRegex = "[^[a-zA-Z]]*"
        let specialPred = NSPredicate.init(format: "SELF MATCHES %@", specialRegex)
        let specialArray: [PinYinSortModel] = sortArray.filter { (model) -> Bool in
            return specialPred.evaluate(with: model.firstLetter)
        } as [PinYinSortModel]
        if specialArray.count > 0 {
            let normalRegex = "[a-zA-Z]"
            let normalPred = NSPredicate.init(format: "SELF MATCHES %@", normalRegex)
            let normalArray: [PinYinSortModel] = sortArray.filter { (model) -> Bool in
                return normalPred.evaluate(with: model.firstLetter)
                } as [PinYinSortModel]
            sortArray.removeAll()
            if normalArray.count > 0 {
                sortArray += normalArray
            }
            let specialModel: PinYinSortModel = PinYinSortModel()
            specialModel.firstLetter = "#"
            specialModel.modelArray = [AnyObject]()
            for model in specialArray {
                specialModel.modelArray! += model.modelArray!
            }
            sortArray.append(specialModel)
        }
       
    }
    
    return sortArray
}

private func getFirstLetter(_ firstLetters: String?) -> String {
    if stringIsNotBlank(firstLetters) {
        return String(firstLetters!.prefix(1))
    } else {
        return ""
    }
}

public func getFirstLetters(_ str: String) -> String {
    // nil或空字符串
    if !stringIsNotBlank(str) {
        return str;
    }
    // 如果没有中文直接返回
    if !isIncludeChinese(str) {
        return str.uppercased()
    }
    
    let pinyin = getPinyin(str)
    let pys: [Substring] = pinyin.split(separator: " ")
    var firstLetters: String = ""
    for subStr in pys {
        if subStr.count > 0 {
            firstLetters += String(subStr.prefix(1))
        }
    }
    return firstLetters.uppercased()
}

private func getPinyin(_ str: String) -> String {
    // 如果没有中文直接返回
    if !isIncludeChinese(str) {
        return str
    }
    
    // 处理首字母是多音字
    let polyPinYinStrs = getPolyPinYinStrs()
    for (name, _) in polyPinYinStrs {
        if str.hasPrefix(name) {
            return getPolyPinYin(str)
        }
    }
    
    // 将拼音首字母装换成大写
    let pinyinStr = getCommonPinYin(str)
    return pinyinStr
}

private func getPolyPinYin(_ str: String) -> String {
    // 处理多音字
    var firstStrPinyin = ""
    let polyPinYinStrs = getPolyPinYinStrs()
    for (name, pinyin) in polyPinYinStrs {
        if str.hasPrefix(name) {
           firstStrPinyin = pinyin
            break;
        }
    }
    let otherStr = String(str.suffix(str.count - 1))
    let otherStrPinyin = getCommonPinYin(otherStr)
    return firstStrPinyin + " " + otherStrPinyin
}

private func getCommonPinYin(_ str: String) -> String {
    // 注意,这里一定要转换成可变字符串
    let mutableString = NSMutableString.init(string: str)
    // 将中文转换成带声调的拼音
    CFStringTransform(mutableString as CFMutableString, nil, kCFStringTransformToLatin, false)
    // 去掉声调(用此方法大大提高遍历的速度)
    let pinyinStr = mutableString.folding(options: String.CompareOptions.diacriticInsensitive, locale: NSLocale.current)
    // 截取大写首字母
    return pinyinStr
}

private func getPolyPinYinStrs() -> [(String, String)] {
    return [("长", "chang"), ("沈", "shen"), ("厦", "xia"), ("地", "di"), ("重", "chong")];
}
